package cn.tedu.tmall.admin.mall.service.impl;

import cn.tedu.tmall.admin.mall.dao.persist.repository.ICategoryRepository;
import cn.tedu.tmall.admin.mall.dao.persist.repository.IGoodsDetailRepository;
import cn.tedu.tmall.admin.mall.dao.persist.repository.IGoodsReposityory;
import cn.tedu.tmall.admin.mall.dao.serch.IGoodsSearchRepository;
import cn.tedu.tmall.admin.mall.pojo.entity.Goods;
import cn.tedu.tmall.admin.mall.pojo.entity.GoodsDatail;
import cn.tedu.tmall.admin.mall.pojo.param.GoodsAddNewParam;
import cn.tedu.tmall.admin.mall.pojo.vo.CategoryStandardVO;
import cn.tedu.tmall.admin.mall.pojo.vo.GoodsListItemVO;
import cn.tedu.tmall.admin.mall.pojo.vo.GoodsStandarVO;
import cn.tedu.tmall.admin.mall.service.IGoodsService;
import cn.tedu.tmall.common.enumerator.ServiceCode;
import cn.tedu.tmall.common.ex.ServiceException;
import cn.tedu.tmall.common.pojo.authentication.CurrentPrincipal;
import cn.tedu.tmall.common.pojo.po.GoodsSearchPO;
import cn.tedu.tmall.common.pojo.vo.PageData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@Slf4j
public class GoodsService implements IGoodsService {
    @Autowired
    private IGoodsReposityory goodsReposityory;
    @Autowired
    private ICategoryRepository categoryRepository;
    @Autowired
    private IGoodsDetailRepository goodsDetailRepository;
    @Autowired
    private IGoodsSearchRepository goodsSearchRepository;

    @Override
    public PageData<GoodsListItemVO> list(Integer pageNum, Integer pageSize) {
        log.debug("开始处理查询商品列表");
        return goodsReposityory.list(pageNum, pageSize);
    }

    @Override
    public PageData<GoodsListItemVO> listByCategory(Long categoryId, Integer pageNum, Integer pageSize) {
        log.debug("开始处理根据ID查询商品");
        return goodsReposityory.listByCategory(categoryId, pageNum, pageSize);
    }

    @Override
    public void add(CurrentPrincipal currentPrincipal, GoodsAddNewParam goodsAddNewParam) {
        // 判断商品类别是否存在
        Long categoryId = goodsAddNewParam.getCategoryId();
        // 根据商品id查询详情
        CategoryStandardVO category = categoryRepository.getStandardById(categoryId);
        if (category == null) {
            String message = "商品类别不存在,类别数据不存在";
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND, message);
        }

        // 判断商品类别是否启用
        if (category.getEnable() != 1) {
            String message = "发布商品失败,选择的类别已经被禁用";
            throw new ServiceException(ServiceCode.ERROR_CONFLICT, message);
        }

        // 选择的类别必须不包含子级类别
        if (category.getIsParent() != 0) {
            String message = "发布商品失败,选择的类别必须不包含子级类别";
            throw new ServiceException(ServiceCode.ERROR_CONFLICT, message);
        }

        Goods goods = new Goods();
        BeanUtils.copyProperties(goodsAddNewParam, goods);
        goods.setCategoryName(category.getName());
        int rows = goodsReposityory.insert(goods);
        if (rows != 1) {
            String message = "发布商品失败，服务器忙，请稍后再尝试";
            throw new ServiceException(ServiceCode.ERROR_INSERT, message);
        }

        // 向mall_goods_detail中插入数据
        GoodsDatail goodsDatail = new GoodsDatail();
        goodsDatail.setGoodsId(goods.getId());
        goodsDatail.setDetail(goodsAddNewParam.getDetail());
        rows = goodsDetailRepository.insert(goodsDatail);
        if (rows != 1) {
            String message = "发布商品失败,服务器繁忙, 请稍后再尝试";
            throw new ServiceException(ServiceCode.ERROR_INSERT, message);
        }
    }

    @Override
    public void rebuildSearch() {
        Integer pageNum = 1;
        Integer pageSize = 3;
        Integer maxPage;
        PageData<GoodsSearchPO> pageData;
        do {
            // 先在数据库中获取信息,然后进行分页
            pageData = goodsReposityory.listSearch(pageNum, pageSize);
            // 获取数据的条数
            maxPage = pageData.getMaxPage();
            List<GoodsSearchPO> list = pageData.getList();
            // 将数据库获取的数据提前缓存到SE中
            goodsSearchRepository.saveAll(list);
            pageNum++;
        } while (pageNum <= maxPage);
    }

    @Override
    public void passCheck(CurrentPrincipal currentPrincipal, Long goodsId, String remarks) {
        log.debug("开始处理【审核通过商品】的业务，参数：{}", goodsId);
        updateCheckById(currentPrincipal, goodsId, CHECK_STATE_PASS, remarks);
    }

    @Override
    public void rejectCheck(CurrentPrincipal currentPrincipal, Long goodsId, String remarks) {
        log.debug("开始处理【拒绝审核商品】的业务，参数：{}", goodsId);
        updateCheckById(currentPrincipal, goodsId, CHECK_STATE_REJECT, remarks);
    }

    @Override
    public void putOn(CurrentPrincipal currentPrincipal, Long id) {
        log.debug("开始处理上架商品的数据");
        updatePutOnById(id,PUT_ON_STATE_ON);
    }

    @Override
    public void pullOff(CurrentPrincipal currentPrincipal, Long id) {
        log.debug("开始处理下架商品的数据");
        updatePutOnById(id,PUT_ON_STATE_OFF);
    }

    @Override
    public void setRecommend(CurrentPrincipal currentPrincipal, Long id) {
        log.debug("开始处理推荐商品的数据");
    }

    @Override
    public void cancelRecommend(CurrentPrincipal currentPrincipal, Long id) {
        log.debug("开始处理推荐商品的数据");
    }

    /**
     * 修改商品的审核状态
     *
     * @param currentPrincipal 当事人
     * @param id               商品ID
     * @param checkState       新的审核状态
     * @param remarks          审核备注
     * @see cn.tedu.tmall.common.consts.data.CommonConsts#CHECK_STATE_UNCHECKED
     * @see cn.tedu.tmall.common.consts.data.CommonConsts#CHECK_STATE_PASS
     * @see cn.tedu.tmall.common.consts.data.CommonConsts#CHECK_STATE_REJECT
     */
    private void updateCheckById(CurrentPrincipal currentPrincipal, Long id, Integer checkState, String remarks) {
        GoodsStandarVO currentGoods = goodsReposityory.getStandardById(id);
        if (currentGoods == null) {
            String message = "将商品的审核状态修改为【" + CHECK_STATE_TEXT[checkState] + "】失败，商品数据不存在！";
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND, message);
        }

        if (currentGoods.getCheckState().equals(checkState)) {
            String message = "将商品的审核状态修改为【" + CHECK_STATE_TEXT[checkState] + "】失败，此商品已经处于" + CHECK_STATE_TEXT[checkState] + "状态！";
            throw new ServiceException(ServiceCode.ERROR_CONFLICT, message);
        }

        Goods updateGoods = new Goods();
        updateGoods.setId(id);
        updateGoods.setCheckState(checkState);
        int rows = goodsReposityory.updateById(updateGoods);
        if (rows != 1) {
            String message = "将商品的审核状态修改为【" + CHECK_STATE_TEXT[checkState] + "】失败，服务器忙，请稍后再尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_UPDATE, message);
        }
    }

    /**
     * 修改商品的上架状态
     *
     * @param id         商品ID
     * @param putOnState 新的上架状态
     * @see cn.tedu.tmall.common.consts.data.MallConsts#PUT_ON_STATE_ON
     * @see cn.tedu.tmall.common.consts.data.MallConsts#PUT_ON_STATE_OFF
     */
    private void updatePutOnById(Long id, Integer putOnState) {
        // 修改商品的上架状态核心逻辑
        // -- 如果商品不存在，不允许修改
        // -- 如果目标状态与当前状态相同，不允许修改
        // -- 如果商品不是“通过审核”状态，不允许修改
        // -- 如果下架，将推荐状态改为“不推荐”
        GoodsStandarVO currentGoods = goodsReposityory.getStandardById(id);
        if (currentGoods == null) {
            String message = "将商品状态修改为【" + PUT_ON_STATE_TEXT[putOnState] + "】失败，商品数据不存在！";
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND, message);
        }

        // 判断目标状态与当前状态相同
        if (currentGoods.getIsPutOn().equals(putOnState)) {
            String message = "将商品状态修改为【" + PUT_ON_STATE_TEXT[putOnState] + "】失败，此商品已经处于" + PUT_ON_STATE_TEXT[putOnState] + "状态！";
            throw new ServiceException(ServiceCode.ERROR_CONFLICT, message);
        }

        // 如果目标状态与当前状态相同，不允许修改
        if (!currentGoods.getCheckState().equals(CHECK_STATE_PASS)) {
            String message = "将商品状态修改为【" + PUT_ON_STATE_TEXT[putOnState] + "】失败，此商品尚未通过审核！";
            throw new ServiceException(ServiceCode.ERROR_CONFLICT, message);
        }

        Goods updateGoods = new Goods();
        updateGoods.setId(id);
        updateGoods.setIsPutOn(putOnState);
        // 如果是上架状态,将修改为推荐商品
        if (putOnState == PUT_ON_STATE_OFF) {
            updateGoods.setIsRecommend(RECOMMEND_STATE_OFF);
        }

        int i = goodsReposityory.updateById(updateGoods);
        if (i > 0) {
            String message = "服务器繁忙,请稍后再拔";
            throw new ServiceException(ServiceCode.ERROR_UPDATE, message);

        }
    }
}
